package com.signway.swmediaplayerdemo.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.PixelFormat;
import android.graphics.Typeface;
import android.opengl.GLSurfaceView;
import android.text.TextPaint;
import android.util.Log;
import android.view.SurfaceHolder;

public class TextView3 extends GLSurfaceView implements SurfaceHolder.Callback, GLDataListener {
	private final String TAG = "TextView3";
	private TextViewListener listener;
	/**
	 * 方向
	 */
	private final int DIR_STATIC = 0;
	private final int DIR_LEFT = 1;
	private final int DIR_RIGHT = 2;
	private final int DIR_UP = 3;
	private final int DIR_DOWN = 4;

	/**
	 * 文本排列方向
	 */
	public final byte TEXT_HORIZONTAL = 0;
	public final byte TEXT_VERTICAL = 1;

	/**
	 * 文本移动的速度
	 */
	private final int MOVE_SLOW = 1; // 1px per 40ms, 25p/s
	private final int MOVE_MIDD = 2; // 1px per 30ms, 33p/s
	private final int MOVE_FAST = 3; // 1px per 22ms, 45p/s
	private final int MOVE_SOFAST = 4; // 2px per 35ms, 57p/s
	private final int MOVE_SSFAST = 5;
	/**
	 * 文本字体类型
	 */
	public final String TYPE_FACE_ARIAL = "Chinese-黑体";
	public final String TYPE_FACE_BLACK = "English-Arial";

	private Paint paintText; // 画笔属性
	private TextPaint textPaint;
	private Paint paintBg; // 画笔属性
	private String content; // 文本內容
	private int content_txt_offset; //文本显示文字偏移
	private char[] textChars; // 文本个数
	private char[][] textLineChars; // 每行显示的文件
	private float size; // 字体大小
	private float length; // 文本长度 px
	private float height; // 文本的高
	private float areaHeight; // 背景区域的高
	private float areaWidth; // 背景区域的宽
	private float x; // 文本x位置
	private float y; // 文本y位置
	private int speed; // 文本速度
	private int moveDirection; // 文本移动的方向
	// private byte compose = TEXT_HORIZONTAL;
	private boolean isDraw = false;
	private boolean mRun = true;
	Bitmap bitmap;
	Matrix matrix = new Matrix();
	private Thread thread;
	
	int sizeSum = 0;
	float sizeWidthMax = 0;
	float sizeOffsetWidthMax = 0;
	float offsetX = 0;

	private float mBigFontBottom;

	private float mBigFontHeight;

	private int strokeSize = 2;
	
	private boolean isDrawLine = false;
	
	private int curTextColor = 0;
	
	private SignwayOpenGLRender glRender = null;

	public TextView3(Context context, float areawidth, float areaheight) {
		super(context);
		this.areaWidth = areawidth;
		this.areaHeight = areaheight;
		Log.i(TAG, "areaWidth = " + this.areaWidth);
		Log.i(TAG, "areaHeight = " + this.areaHeight);
		init();
	}

	private void init() {
		this.setZOrderOnTop(true);
		this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
		mHolder = this.getHolder();
		mHolder.setFormat(PixelFormat.TRANSPARENT);
		mHolder.addCallback(this);
		paintText = new Paint();
		paintText.setAntiAlias(true);
		paintBg = new Paint();
		
		FontMetrics fm = paintText.getFontMetrics();

		mBigFontBottom = fm.bottom;

		mBigFontHeight = fm.bottom - fm.top;
		
		glRender = new SignwayOpenGLRender();
		glRender.dataListener = this;
	}

	@Override
	public void updateData() {
		if (!isDraw){
			return;
		}
		
		drawText(null);
		moveText();
	}
	
	@Override
	public boolean canWork(){
		if(isDraw){
			return true;
		}else{
			return false;
		}
	}
	
	private boolean mHasCreated = false;
	private SurfaceHolder mHolder;
	private Canvas mCanvas;
	private int mSleep = 30;

	public void setTextView(String content, int size, int dir, int speedtype,
                            String typeface, String textColor, String bgColor, String alphaPer,
                            int time, int moveSpeed, TextViewListener _listener, Boolean isDrawStroke) {
		Log.v(TAG, "speedtype = " + speedtype + " moveSpeed = " + moveSpeed + " size = " + size);
//		this.content = content;
		this.size = size;
		this.moveDirection = dir;
		this.isDrawLine = isDrawStroke;
		
		if (size >= areaHeight) {// 自适应
			this.size = areaHeight - 3;
			paintText.setTextSize(areaHeight);
		} else {
			paintText.setTextSize(size);
		}
		if (textColor != null) {
			curTextColor = Color.parseColor(textColor);
			paintText.setColor(Color.parseColor(textColor));
		}
		
//		paintText.setTypeface(Main.ttfFontFace);
		int alpha = 0;
		if (bgColor != null) {
			int alphaP = 0;
			try{
				alphaP = Integer.parseInt(alphaPer.substring(0,
						alphaPer.length() - 1));
			}catch(Exception e){
				alphaP = 100;
			}
			
			if(alphaP < 0 || alphaP > 100){
				alphaP = 100;
			}
			
			alpha = (100 - alphaP) * 255 / 100;
			// this.setBackgroundColor(Color.parseColor(bgColor));
			// getBackground().setAlpha(255 - alpha);
			paintBg.setColor(Color.parseColor(bgColor));
			paintBg.setAlpha(alpha);
		}
		if (typeface != null) {
			setTypeface(typeface);
		}
		Log.v(TAG, "moveDirection = " + moveDirection);
		if (content != null) {
			if ((moveDirection == DIR_STATIC) || (moveDirection == DIR_UP)
					|| (moveDirection == DIR_DOWN)) {
				textLineChars = new char[2048][256];

				textChars = content.toCharArray();
				length = paintText.measureText(content);
				if (content.length() != 0) {
					height = paintText.measureText(textChars, 0, 1);
				}

				int lines = prepareChars();
				if (lines > 0) {
					height = lines * (size + 3);
				}
			} else {
				if (content.contains("\n")
						&& (moveDirection == DIR_LEFT || moveDirection == DIR_RIGHT)) {
					content.replace("\n", "  ");
				}

				length = paintText.measureText(content);
				this.content = content;
				textChars = content.toCharArray();
				
				if (content.length() != 0) {
					height = paintText.measureText(textChars, 0, 1);
				}
				
				sizeWidthMax = areaWidth*4;
				sizeOffsetWidthMax = areaWidth*2;
				
				if(moveDirection == DIR_LEFT){
					resetDirLeftRightInfo();
				}else{
					resetDirRightLeftInfo();
				}
			}

			setSpeed(speedtype);
			initLocation(dir);
			frameCount = 0;
			listener = _listener;
			
			this.speed = moveSpeed;
			isDraw = true;
			
			if(glRender != null){
				glRender.textSize = (int)paintText.getTextSize();
				glRender.areaW = areaWidth;
				glRender.areaH = areaHeight;
				glRender.alpha = alpha;
				glRender.textColor = Color.parseColor(textColor);
				glRender.bgColor = Color.parseColor(bgColor);
				this.setRenderer(glRender);
			}
		}
	}

	private int prepareChars() {
		int lines = 0;

		for (int i = 0; i < textChars.length;) {
			int k = 0;
			float w = 0;
			float paintWidth = 0;

			for (int j = 0; (j < areaWidth) && (i < textChars.length); j += w) {
				if ((textChars[i] == 0xD) && (textChars[i] == 0xA)) {
					i += 2;
					break;
				}

				if (textChars[i] == 0xD || textChars[i] == 0xA) {
					i++;
					break;
				}

				w = paintText.measureText(textChars, i, 1);
				if (((w + paintWidth) > areaWidth) && (k > 0)) {
					break;
				}

				paintWidth += w;
				textLineChars[lines][k] = textChars[i];
				k++;
				i++;
			}

			lines++;
			if (lines >= 2048) {
				break;
			}
		}

		return lines;
	}

	// 设置字体类型
	private void setTypeface(String typeface) {
		if (typeface.equals(TYPE_FACE_ARIAL)) {
			paintText.setTypeface(Typeface.MONOSPACE);
		} else if (typeface.equals(TYPE_FACE_BLACK)) {
			paintText.setTypeface(Typeface.SANS_SERIF);
		}
	}

	// 设置文本移动的速度
	private int setSpeed(int speedtype) {
//		switch (speedtype) {
//		case MOVE_SLOW:
//			mSleep = 40;
//			return 1;
//		case MOVE_MIDD:
//			mSleep = 30;
//			return 1;
//		case MOVE_FAST:
//			mSleep = 22;
//			return 1;
//		case MOVE_SOFAST:
//			mSleep = 10;
//			return 2;
//		case MOVE_SSFAST:
//			mSleep = 5;
//			return 2;
//		}

		mSleep = 10;//22;
		return 1;
	}

	// 初始化文本的位置
	private void initLocation(int dir) {
		switch (dir) {
		case DIR_STATIC:
			x = 0;
			y = size;
			break;
		case DIR_UP:
			y = areaHeight + size;
			break;
		case DIR_DOWN:
			y = 0 - height;
			break;
		// y = -height;
		// break;
		case DIR_LEFT:
			x = areaWidth;
			offsetX = x;
			break;
		case DIR_RIGHT:
			x = 0 - length;
			if(length > sizeWidthMax){
				offsetX = 0 - sizeWidthMax;
			}else{
				offsetX = x;
			}
			break;
		// x = -length;
		// break;
		}
	}

	private void textDrawSideLine(Canvas canvas, String text, Paint paint, float x, float y, boolean isStroke){
		
		if(isDrawLine){
			paint.setColor(Color.BLACK);
			paint.setStrokeWidth(3);
			paint.setStyle(Style.FILL_AND_STROKE);
			paint.setFakeBoldText(false);
			//paint.setShadowLayer(1, 0, 0, 0);
			
			canvas.drawText(text, x, y, paint);
		}
	
		paint.setColor(curTextColor);
		paint.setStrokeWidth(0);
		paint.setStyle(Style.FILL_AND_STROKE);
		paint.setFakeBoldText(false);
	//	paint.setShadowLayer(0, 0, 0, 0);
		canvas.drawText(text, x, y, paint);
	}
	
	int frameCount = 0;

	private void drawText(Canvas canvas) {
		drawLHText(canvas);
		
//		canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
////		Log.v(TAG, "---text---lockCanvas11 " + PublicTools.getCurTime());
//		if (isDraw && mHasCreated) {
//			// if( frameCount++ < 2 ){
//			canvas.drawPaint(paintBg);
////			canvas.drawARGB(paintBg.getAlpha(), (paintBg.getColor()>>16) & 0xFF, (paintBg.getColor()>>8) & 0xFF, paintBg.getColor() & 0xFF);
////			Rect rect = new Rect(0, 0, (int)areaWidth, (int)areaHeight);
////	        canvas.drawRect(rect, paintBg); 
////			Log.v(TAG, "---text---lockCanvas12 " + PublicTools.getCurTime());
//			// }
//			// if (compose == TEXT_HORIZONTAL) {
//			if (moveDirection == DIR_LEFT) {
//				drawLHText(canvas);
//				// } else if (compose == TEXT_VERTICAL) {
//			} else if (moveDirection == DIR_RIGHT) {
//				drawRHText(canvas);
//			} else {
//				drawVText(canvas);
//			}
//		}
	}
	
	private void drawRHText(Canvas c) {
		c.save();
		c.clipRect(0, 0, areaWidth, areaHeight);
		String str = content;
		
		//当数据很大时，只能画某一个区间的数据出来就可以了
		//可根据x<-100,找出-100位置的第一个文字，结尾在当前位置偏移2500后，只需要画出这个区间的文字就行
		if(length > sizeWidthMax){
			if(offsetX > (sizeOffsetWidthMax*-1) && (content_txt_offset > 0)){
				//x坐标已经偏移到了左边最末端，需要将x值重复开始偏移，显示的数据也需要重新整理
				
				//左边从头开始，计算出可以删除2倍区域宽数据
				int offSize = content_txt_offset;
				float offWidth = 0;
				int tempSum = 0;
				while(offSize < textChars.length && offSize >= 0){
					float wordW = paintText.measureText(content, offSize, offSize+1);
					if((offWidth + wordW) < sizeOffsetWidthMax){
						offWidth += wordW;
						tempSum += 1;
						offSize -= 1;
					}else{
						break;
					}
				}
				
				offsetX -= offWidth;
				content_txt_offset -= tempSum;
				if(content_txt_offset < 0){
					content_txt_offset = 0;
				}
				
				offSize = content_txt_offset;
				offWidth = 0;
				sizeSum = 0;
				while((offSize+sizeSum) < textChars.length){
					float wordW = paintText.measureText(content, offSize+sizeSum, offSize+sizeSum+1);
					if((offWidth + wordW) < (sizeWidthMax+areaWidth)){
						offWidth += wordW;
						sizeSum += 1;
					}else{
						break;
					}
				}
				
				str = content.substring(content_txt_offset, (int)(content_txt_offset+sizeSum));
			}else{
				//x值还在可控制范围内，只需要当当前值一直左移显示就可以
				str = content.substring(content_txt_offset, (int)(content_txt_offset+sizeSum));
			}
		}else{
			str = content;
		}
		
		float start = x;
		if(length > sizeWidthMax){
			start = offsetX;
		}
	//	c.drawText(str, start, areaHeight / 2 + size / 2 - size / 5, paintText);
		textDrawSideLine(c,str,paintText,start,areaHeight / 2 + size / 2 - size / 5,true);
	//	drawStrokeText(c,str,paintText,start,areaHeight / 2 + size / 2 - size / 5,true);
		// Log.v(TAG, "X:" + x + "content = " + content);
		c.restore();
	}

	// 绘制横向文本
	private void drawLHText(Canvas c) {
//		c.save();
//		c.clipRect(0, 0, areaWidth, areaHeight);
		String str = content;
		
		//当数据很大时，只能画某一个区间的数据出来就可以了
		//可根据x<-100,找出-100位置的第一个文字，结尾在当前位置偏移2500后，只需要画出这个区间的文字就行
		if(length > sizeWidthMax){
			if(offsetX < (sizeOffsetWidthMax*-1)){
				//x坐标已经偏移到了左边最末端，需要将x值重复开始偏移，显示的数据也需要重新整理
				
				//左边从头开始，计算出可以删除2倍区域宽数据
				int offSize = content_txt_offset;
				float offWidth = 0;
				int tempSum = 0;
				while((offSize+tempSum) < textChars.length){
					float wordW = paintText.measureText(content, offSize+tempSum, offSize+tempSum+1);
					if((offWidth + wordW) < sizeOffsetWidthMax){
						offWidth += wordW;
						tempSum += 1;
					}else{
						break;
					}
				}
				
				offsetX += offWidth;
				content_txt_offset += tempSum;
				
				offSize = content_txt_offset;
				offWidth = 0;
				sizeSum = 0;
				while((offSize+sizeSum) < textChars.length){
					float wordW = paintText.measureText(content, offSize+sizeSum, offSize+sizeSum+1);
					if((offWidth + wordW) < (sizeOffsetWidthMax+areaWidth)){
						offWidth += wordW;
						sizeSum += 1;
					}else{
						break;
					}
				}
				
				str = content.substring(content_txt_offset, (int)(content_txt_offset+sizeSum));
			} else{
				//x值还在可控制范围内，只需要当当前值一直左移显示就可以
				str = content.substring(content_txt_offset, (int)(content_txt_offset+sizeSum));
			}
		}else{
			str = content;
		}
		
		float start = x;
		if(length > sizeWidthMax){
			start = offsetX;
		}
		
		if(glRender != null){
			glRender.textContent = str;
			glRender.textX = start;
			glRender.textY = areaHeight / 2 + size / 2 - size / 8;
		}

	//	c.drawText(str, start, areaHeight / 2 + size / 2 - size / 5, paintText);
//		textDrawSideLine(c,str,paintText,start,areaHeight / 2 + size / 2 - size / 5,true);
//	//	c.drawT
//	//	drawStrokeText(c,str,paintText,start,areaHeight / 2 + size / 2 - size / 5,true);
//		// Log.v(TAG, "X:" + x + "content = " + content);
//		c.restore();
		
//		Log.v(TAG, "---text---lockCanvas12 " + PublicTools.getCurTime());
	}

	
	private void drawStrokeText(Canvas canvas, String text, Paint paint, float x, float y, boolean isStroke){

			paint.setColor(Color.BLUE);
			
			paint.setStrokeWidth(2);
			paint.setStyle(Style.STROKE);
			canvas.drawText(text, x, y, paint);
			
			paintText.setAntiAlias(true);
		

			paint.setColor(Color.WHITE);
			 
			canvas.drawText(text, x, y, paint);

	}
	// 绘制纵向文本
	private void drawVText(Canvas c) {
		c.save();
		c.clipRect(0, 0, areaWidth, areaHeight);
		for (int line = 0; line < textLineChars.length; line++) {
			c.drawText(String.valueOf(textLineChars[line], 0,
					textLineChars[line].length), x, y + line * (size + 3),
					paintText);
			
			
		}
		
		c.restore();
	}

	void ClearDraw() {
		Canvas canvas = mHolder.lockCanvas(null);
		canvas.drawColor(Color.BLACK);// 清除画布
		mHolder.unlockCanvasAndPost(canvas);
	}
	
	private void moveText() {
		//speed = 3;
		switch (moveDirection) {
		case DIR_UP:
			y -= speed;
			if (y + height <= size) {
				y = areaHeight + size;
				if (listener != null) {
					listener.OnTextOverListener();
				}
			}
			break;
		case DIR_DOWN:
			y += speed;
			if (y > areaHeight) {
				y = 0 - height;
				if (listener != null) {
					listener.OnTextOverListener();
				}
			}
			break;
		// y += speed;
		// if (y >= areaHeight) {
		// y = -size;
		// if(listener != null){
		// listener.OnTextOverListener();
		// }
		// }
		// break;
		case DIR_LEFT:
			x -= speed;
			offsetX -= speed;
			if (x + length <= 0) {
				x = areaWidth;
				resetDirLeftRightInfo();
				if (listener != null) {
					listener.OnTextOverListener();
				}
			}
//			if(content_txt_offset < content_txt_size){
//				content_txt_offset++;
//			}
			break;
		case DIR_RIGHT:
			x += speed;
			offsetX += speed;
			if (x > areaWidth) {
				x = 0 - length;
				resetDirRightLeftInfo();
				if (listener != null) {
					listener.OnTextOverListener();
				}
			}
			break;
		// x += speed;
		// if (x >= areaWidth) {
		// x = -length;
		// if(listener != null){
		// listener.OnTextOverListener();
		// }
		// }
		// break;
		default:
			break;
		}
	}
	
	private void resetDirLeftRightInfo(){
		offsetX = areaWidth;
		content_txt_offset = 0;
		
		int offSize = content_txt_offset;
		float offWidth = 0;
		sizeSum = 0;
		while((offSize+sizeSum) < textChars.length){
			float wordW = paintText.measureText(content, offSize+sizeSum, offSize+sizeSum+1);
			if((offWidth + wordW) < sizeWidthMax){
				offWidth += wordW;
				sizeSum += 1;
			}else{
				break;
			}
		}
	}
	
	private void resetDirRightLeftInfo(){
		if(length > sizeWidthMax){
			offsetX = 0 - sizeWidthMax;
			
			content_txt_offset = textChars.length-1;
			
			int offSize = content_txt_offset;
			float offWidth = 0;
			sizeSum = 0;
			while((offSize < textChars.length) && (offSize >= 0)){
				float wordW = paintText.measureText(content, offSize, offSize+1);
				if((offWidth + wordW) < sizeWidthMax){
					offWidth += wordW;
					sizeSum += 1;
					offSize -= 1;
				}else{
					break;
				}
			}
			
			content_txt_offset = offSize;
		}else{
			offsetX = 0 - length;
			content_txt_offset = 0;
		}
	}

	public void setBgAlpha(int alphaPer) {
		if (alphaPer < 0 || alphaPer > 100) {
			alphaPer = 100;
		}
		int alpha = (100 - alphaPer) * 255 / 100;
		if (glRender != null) {
			glRender.alpha = alpha;
		}
	}

	public void setTextColor(String textColor) {
		curTextColor = Color.parseColor(textColor);
		if (glRender != null) {
			glRender.textColor = curTextColor;
		}
	}

	public void cancel() {
		mRun = false;
	}

	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
	}

	@Override
	protected void onDetachedFromWindow() {
		Log.i(TAG, "onDetachedFromWindow");
		mRun = false;
		
		if(glRender != null){
			glRender.onDestroy();
		}
//		try {
//			thread.join();
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		super.onDetachedFromWindow();
	}

//	@Override
//	public void surfaceCreated(SurfaceHolder holder) {
//		this.mHasCreated = true;
//	}
//
//	@Override
//	public void surfaceChanged(SurfaceHolder holder, int format, int width,
//			int height) {
//	}
//
//	@Override
//	public void surfaceDestroyed(SurfaceHolder holder) {
//		this.mHasCreated = false;
//	}
}
